/* Copyright ©, 2022, ECARX (Hubei) Technology Co., Ltd. All rights reserved.
 *
 * NOTICE: This file contains information which is confidential and proprietary to ECARX
 * (Hubei) Technology Co., Ltd. and/or other developers. No license to any intellectual
 * property rights contained within this file is either granted or implied except as may be
 * provided in an agreement with ECARX (Hubei) Technology Co., Ltd.
 *
 * Any unauthorized copying or distribution of content from this file in whole or in part
 * is prohibited.
 */
#ifndef ECARX_VHAL_CORE_PROPERTY_TIMER_BUILD_H
#define ECARX_VHAL_CORE_PROPERTY_TIMER_BUILD_H

#include <functional>
#include <type_traits>
#include <vector>

#include "cstdint"
#include "IProperty.h"
#include "vhal_core/utils/convert.h"

namespace ecarx::vhal::core::property {

/// 初始化属性值函数
template <typename T>
using InitFn = std::function<T()>;

/// 属性值处理函数
template <typename T>
using PropValueFn = std::function<T(const T&)>;

/// 属性状态处理函数
using PropStatusFn = std::function<PropertyStatus(const PropertyStatus)>;

/// 属性设置动作函数
template <typename T>
using SetFn = std::function<void(const T&)>;

/// 信号监听函数
using SignalChangedCallback = std::function<void()>;

/// 定时器任务函数
using TimerFn = std::function<void()>;

/// PropChange函数
using PropValueChangeCallback = std::function<void(const VehiclePropValue&)>;

/// 定义功能描述终止符号
template <typename _TY, typename PropBuilder>
class TimerBuilder : public PropBuilder {
    Area* mArea;

  public:
    TimerBuilder(Area* area) : PropBuilder(area->getIProperty()), mArea(area) {}

    template <typename... SIGNALS>
    TimerBuilder& subscribeSignals(SignalChangedCallback&& _callback, SIGNALS... arg) {
        auto signalCallback = [_callback](Area* const, int64_t timestamp) { _callback(); };
        (mArea->registerSignalCallback(toInt(arg), signalCallback), ...);
        return *this;
    }

    TimerBuilder& onMsgEvent(uint32_t msgId, TimerFn&& fn) {
        mArea->getIProperty()->addTimeTask(msgId, std::move(fn));
        return *this;
    }

    template <typename Prop, typename Area>
    TimerBuilder& onPropertyValueChange(Prop&& prop, Area&& area,
                                        PropValueChangeCallback&& _callback) {
        mArea->registerPropValueChangeCallback(toInt(prop), static_cast<int32_t>(area),
                                               std::move(_callback));
        return *this;
    }
};

}  // namespace ecarx::vhal::core::property

#endif